﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace LightGameLibs
{
    /// <summary>
    /// 继承这个类来实现自己的MonoBehaviour事件系统
    /// </summary>
    /// <typeparam tag="TEnum"></typeparam>
    public class MBEventMgr<TEnum> : MonoBehaviour
    {
        [System.Serializable]
        public class Enum2MBEventDict : SerializableDictionary<TEnum, SerializableEvent> { }
        [System.Serializable]
        public class Enum2NoArgEventDict : SerializableDictionary<TEnum, UnityEvent> { }

        [SerializeField]
        private Enum2MBEventDict m_eventDict;
        [SerializeField]
        private Enum2NoArgEventDict m_noArgEventDict;

        public void Invoke(string enumName)
        {
            object tag = Enum.Parse(typeof(TEnum), enumName);
            if (null == tag)
            {
                DebugMgr.Log(DebugTag.EVENT, "Enum Type Not Exist");
                return;
            }

            TEnum enumTag = (TEnum)tag;
            if (!CheckNoArgEventDict(enumTag))
            {
                return;
            }

            m_noArgEventDict[enumTag].Invoke();
        }

        public void Invoke(TEnum tag, EventArgs arg = null)
        {
            if (!CheckEventDict(tag))
            {
                return;
            }

            if (null != arg)
            {
                m_eventDict[tag].Invoke(arg);
            }

            if (!CheckNoArgEventDict(tag))
            {
                return;
            }

            m_noArgEventDict[tag].Invoke();
        }

        public void AddListener(TEnum tag, UnityAction<EventArgs> act)
        {
            if (!CheckEventDict(tag))
            {
                return;
            }

            m_eventDict[tag].AddListener(act);
        }

        public void RemoveListener(TEnum tag, UnityAction<EventArgs> act)
        {
            if (!CheckEventDict(tag))
            {
                return;
            }

            m_eventDict[tag].RemoveListener(act);
        }

        public void AddListener(TEnum tag, UnityAction act)
        {
            if (!CheckNoArgEventDict(tag))
            {
                return;
            }

            m_noArgEventDict[tag].AddListener(act);
        }

        public void RemoveListener(TEnum tag, UnityAction act)
        {
            if (!CheckNoArgEventDict(tag))
            {
                return;
            }

            m_noArgEventDict[tag].RemoveListener(act);
        }

        private bool CheckEventDict(TEnum tag)
        {
            bool ret = true;
            if (null == m_eventDict)
            {
                DebugMgr.LogError(DebugTag.EVENT, "EventDict Not Reference");
                ret = false;
            }

            if (!m_eventDict.ContainsKey(tag))
            {
                DebugMgr.LogWarning(DebugTag.EVENT, "Key Not Contain In EventDict");
                ret = false;
            }
            return ret;
        }

        private bool CheckNoArgEventDict(TEnum tag)
        {
            bool ret = true;
            if (null == m_noArgEventDict)
            {
                DebugMgr.LogError(DebugTag.EVENT, "EventDict Not Reference");
                ret = false;
            }

            if (!m_noArgEventDict.ContainsKey(tag))
            {
                DebugMgr.LogWarning(DebugTag.EVENT, "Key Not Contain In EventDict");
                ret = false;
            }
            return ret;
        }
    }
}
